package tech.xs.common.framework.init.db.sql;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import tech.xs.common.framework.init.db.domain.exception.SqlBuildException;
import tech.xs.common.framework.domain.constant.Symbol;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *
 */
public abstract class SqlBuilder {

    /**
     * 表名
     */
    private String tableName;

    /**
     * 唯一字段
     */
    private String uniqueField;

    /**
     * 多个字段确定唯一属性
     */
    private List<String> uniqueFieldArray;

    public SqlBuilder table(String tableName) {
        this.tableName = tableName;
        return this;
    }

    public SqlBuilder uniqueField(String uniqueField) {
        this.uniqueField = uniqueField;
        return this;
    }

    public SqlBuilder uniqueField(List<String> uniqueField) {
        this.uniqueFieldArray = uniqueField;
        return this;
    }

    /**
     * 获取[判断数据是否存在数据库中]SQL
     *
     * @param data 数据
     * @return sql
     */
    public String buildExistSql(Map<String, Object> data) {
        String queryTableSql = "select count(1) FROM `" + tableName + "`";
        if (StrUtil.isNotBlank(uniqueField)) {
            return buildUniqueFieldExistSql(data, queryTableSql);
        }
        if (ArrayUtil.isNotEmpty(uniqueFieldArray)) {
            return buildUniqueFieldArrayExistSql(data, queryTableSql);
        }
        throw new SqlBuildException("buildExistSql 异常 uniqueField 与 uniqueFieldArray 至少有一个不为空");
    }

    public String buildUniqueFieldArrayExistSql(Map<String, Object> data, String queryTableSql) {
        String escapeCharacter = getEscapeCharacter();
        StringBuilder sql = new StringBuilder(queryTableSql + " where ");
        for (String field : uniqueFieldArray) {
            if (!data.containsKey(field)) {
                sql.append(escapeCharacter).append(field).append(escapeCharacter).append(" is null and ");
                continue;
            }
            Object v = data.get(field);
            if (v instanceof Integer || v instanceof Long) {
                sql.append(escapeCharacter).append(field).append(escapeCharacter).append(" = ").append(v).append(" and ");
            } else {
                sql.append(escapeCharacter).append(field).append(escapeCharacter).append(" = '").append(v).append("' and ");
            }
        }
        sql = new StringBuilder(sql.substring(0, sql.length() - " and ".length()));
        return sql.toString();
    }

    public String buildUniqueFieldExistSql(Map<String, Object> data, String queryTableSql) {
        String escapeCharacter = getEscapeCharacter();
        Object v = data.get(uniqueField);
        if (v instanceof Integer || v instanceof Long) {
            return queryTableSql + " where " + escapeCharacter + uniqueField + escapeCharacter + " = " + data.get(uniqueField);
        } else {
            return queryTableSql + " where " + escapeCharacter + uniqueField + escapeCharacter + " = '" + data.get(uniqueField) + "'";
        }
    }

    /**
     * 获取[插入数据]SQL
     *
     * @param data 数据值
     * @return sql
     */
    public String buildInsertSql(Map<String, Object> data) {
        String fieldsStr = "";
        String valuesStr = "";
        Set<String> keySet = data.keySet();
        String escapeCharacter = getEscapeCharacter();
        for (String key : keySet) {
            fieldsStr = fieldsStr + escapeCharacter + key + escapeCharacter + Symbol.COMMA;
            valuesStr = valuesStr + Symbol.SINGLE_QUOTES + data.get(key) + Symbol.SINGLE_QUOTES + Symbol.COMMA;
        }
        fieldsStr += "CREATED_BY,CREATED_TIME,UPDATED_BY,UPDATED_TIME";
        String date = DateUtil.now();
        valuesStr += "0,'" + date + "',0,'" + date + "'";
        return "INSERT INTO " + tableName + " (" + fieldsStr + ") VALUES (" + valuesStr + ");";
    }

    abstract String getEscapeCharacter();

}
